home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
318_01
/
redsys.c
< prev
Wrap
C/C++ Source or Header
|
1990-06-16
|
14KB
|
756 lines
/*
RED operating system module -- Full C version
Source: redsys.c
Version: June 18, 1986; January 18, 1990.
Written by
Edward K. Ream
166 N. Prospect
Madison WI 53705
(608) 257-0802
PUBLIC DOMAIN SOFTWARE
This software is in the public domain.
See red.h for a disclaimer of warranties and other information.
*/
#include "red.h"
#ifdef MICRO_SOFT
#include <bios.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys\types.h>
#include <sys\stat.h>
#endif
#ifdef TURBOC
#include <alloc.h>
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <mem.h>
#include <sys\stat.h>
#endif
static char sysinbuf[128]; /* file buffer */
static int sysincnt; /* index to sysinbuf[] */
static char syscbuf[MAXLEN]; /* typeahead buffer */
static int sysccnt; /* index for syscbuf[] */
static int sysrcnt; /* repeat count */
static int syslastc; /* last character */
static int systopl,systopy,sysnl; /* interrupt info */
/*
NOTE: This module should contain all routines that
might have to be changed for different compilers or
different operating systems.
Some routines in this module probably will probably
work regardless of operating system. These I have
called PORTABLE routines.
*/
/*
Return a pointer to a block of n contiguous bytes.
Return NULL (i.e., 0) if fewer than n bytes remain.
*/
char *
sysalloc(n)
int n;
{
char * p;
p = (char *) malloc(n);
TRACEP("sysalloc",
sl_lpout(); sl_iout(n);
sl_sout(") returns "); sl_pout(p); sl_cout('\n'));
return p;
}
/*
o Wait for next character from the console.
o Do NOT echo the character.
o Print any waiting lines if there is no input ready.
o Swap out any dirty blocks if nothing else is happening.
(The SWAP constant enables this feature)
*/
int
syscin(void)
{
int c;
int main_byte, aux_byte;
SL_DISABLE();
for(;;) {
c = syscstat();
if (c != -1) {
break;
}
/* Output queued ? */
if (hasint && sysnl > 0) {
/* Print one line. */
bufout(systopl, systopy, sysnl);
}
#ifdef SWAP
/* Do not interrupt screen activity. */
if (sysnl == 0) {
/* Swap out one dirty buffer. */
swap_one();
}
#endif
}
#ifdef IBM
main_byte = c & 0xff;
aux_byte = (c & 0xff00) >> 8;
TRACEP("syscin",
sl_sout(" main: "); sl_iout(main_byte);
sl_sout(" aux: "); sl_iout(aux_byte);
sl_cout('\n'));
/* Handle cursor keys and the numeric keypad. */
if (main_byte == 0) switch (aux_byte) {
case 71: return HOME_KEY; /* Home key. */
case 79: return END_KEY; /* End key. */
case 73: return PAGE_UP; /* Page up key. */
case 81: return PAGE_DN; /* Page down key. */
case 82: return UP_INS; /* Insert key */
case 83: return DEL2; /* Delete Key */
case 77: return RIGHT; /* Arrow keys. */
case 75: return LEFT;
case 72: return UP;
case 80: return DOWN;
}
#endif
return c & 0x7f;
}
/*
Close an unbuffered file.
Return OK (0) or ERROR (-1).
*/
int
sysclose(int fd)
{
TRACEP("sysclose", sl_lpout(); sl_iout(fd); sl_rpout());
close(fd);
}
/*
Copy a file name from args to buffer.
This routine is SEMI-PORTABLE, since it depends,
to a certain extent, on what constitutes a file name.
*/
void
syscopfn(char *args, char *buffer)
{
int n;
TRACEP("syscopfn", sl_lpout();
sl_sout(args); sl_csout();
sl_pout(buffer); sl_rpout());
for (n = 0;
n < SYSFNMAX -1 && args [n] != '\0' && args [n] != ' ';
n++) {
buffer [n] = args [n];
}
buffer[n] = '\0';
}
/*
Create an file for use by sysread and syswrite.
Erase it if it exists and leave it open for read/write access.
Return a small positive int or ERROR (-1).
*/
int
syscreat(char * filename)
{
int result;
TRACEP("syscreat", sl_lpout(); sl_sout(filename));
#ifdef MICRO_SOFT
_fmode = O_BINARY;
result = creat(filename, S_IREAD | S_IWRITE);
_fmode = O_TEXT;
#endif
#ifdef TURBOC
_fmode = O_BINARY;
result = creat(filename, S_IREAD | S_IWRITE);
_fmode = O_TEXT;
#endif
TRACE("syscreat",
sl_sout(") returns "); sl_iout(result); sl_cout('\n'));
return result;
}
/*
Return -1 if no character is ready from the keyboard.
Otherwise, return the character itself.
This routine handles typeahead buffering. It would
also handle the repeat key, if that feature is used,
which it is NOT at present. The code enclosed in
comments handles the repeat key.
*/
int
syscstat(void)
{
int c;
SL_DISABLE();
/* Always look for another character. */
#ifdef MICRO_SOFT
c = _bios_keybrd(_KEYBRD_READY);
if (c == 0) {
c = -1;
}
else {
_bios_keybrd(_KEYBRD_READ);
}
#endif
#ifdef TURBOC
c = bioskey(1);
if (c == 0) {
c = -1;
}
else {
bioskey(0);
}
#endif
return c;
}
/*
Execute args as if they were entered from the command line.
*/
void
sysexec(char *args)
{
SL_DISABLE();
#ifdef MICRO_SOFT
system(args);
puts("\nPress any key to resume editing: ");
syscin();
#endif
#ifdef TURBOC
system(args);
puts("\nPress any key to resume editing: ");
syscin();
#endif
}
/*
Return TRUE if the file exists and FALSE otherwise.
This routine is PORTABLE.
*/
int
sysexists(char * filename)
{
int fd;
TRACEPB("sysexists", sl_lpout(); sl_sout(filename); sl_rpout());
if ((fd = sysopen(filename)) != ERROR) {
sysclose(fd);
RETURN_BOOL("sysexists", TRUE);
}
else {
RETURN_BOOL("sysexists", FALSE);
}
}
/*
Close and flush a file opened with sysfopen or sysfcreat.
Return OK (0) or ERROR (-1).
*/
int
sysfclose(FILE *fd)
{
TRACEP("sysfclose", sl_lpout(); sl_pout(fd); sl_rpout());
return fclose(fd);
}
/*
Create a buffered output file for use with sysfputs.
The file is cleared (erased) if it already exists.
A pointer to FILE is returned if all goes well.
NULL (0), is returned if the file can not be created.
*/
FILE *
sysfcreat(char *filename)
{
FILE * f;
TRACEP("sysfcreat", sl_lpout(); sl_sout(filename));
#ifdef MICRO_SOFT
f = fopen(filename, "w");
#endif
#ifdef TURBOC
f = fopen(filename, "w");
#endif
TRACE("sysfcreat",
sl_sout(") returns "); sl_pout(f); sl_cout('\n'));
return f;
}
/*
Read the next line from buffered input file.
End the line with an '\n'.
Return the count of the characters read.
Return ERROR (-1) on end-of-file.
*/
int
sysfgets(FILE *fd, char *buffer, int maxlen)
{
int c, count;
TRACEP("sysfgets", sl_lpout();
sl_pout(fd); sl_csout();
sl_pout(buffer); sl_csout();
sl_iout(maxlen));
count = 0;
while(1) {
c = sysgetc(fd);
if (c == '\r') {
/* Ignore pseudo newline. */
continue;
}
else if (c == EOF_MARK || c == ERROR) {
buffer [min(count, maxlen-2)] = '\n';
buffer [min(count, maxlen-1)] = '\0';
TRACE("sysfgets", sl_sout(") returns ERROR\n"));
return ERROR;
}
else if (c == '\n') {
buffer [min(count, maxlen-2)] = '\n';
buffer [min(count, maxlen-1)] = '\0';
TRACE("sysfgets",
sl_sout(") returns ");
sl_iout(count);
sl_cout('\n'));
return count;
}
else if (count < maxlen - 2) {
buffer [count++] = c;
}
else {
count++;
}
}
}
/*
Write n BYTES from the buffer to the END of an unbuffered file.
Return ERROR (-1) or 1.
*/
int
sysflush(int fd, char * buffer, int n)
{
int result;
#ifdef MICRO_SOFT
result = (write(fd, buffer, n) == -1) ? ERROR : 1;
#endif
#ifdef TURBOC
result = (write(fd, buffer, n) == -1) ? ERROR : 1;
#endif
return result;
}
/*
Open a buffered input file for use by sysfgets and sysgetc.
Return FILE or NULL if the file does not exist.
*/
FILE *
sysfopen(char *filename)
{
FILE * f;
#ifdef MICRO_SOFT
f = fopen(filename, "r");
#endif
#ifdef TURBOC
f = fopen(filename, "r");
#endif
return f;
}
/*
Get the next characer from a file opened by sysfopen.